home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’95 / ProcessBar™ / Code / Sources / sample drag.c < prev    next >
Encoding:
Text File  |  1995-09-10  |  5.8 KB  |  209 lines  |  [TEXT/MMCC]

  1. // File "sample drag.c" -
  2.  
  3. #include <Drag.h>
  4.  
  5. #include "main.h"
  6. #include "floaters.h"
  7. #include "sample drag.h"
  8. #include "sample win.h"
  9.  
  10. // ***********************************************************************************
  11. // Global Declarations 
  12.  
  13. extern GlobalsRec glob;
  14.  
  15. // ***********************************************************************************
  16. // ***********************************************************************************
  17.  
  18. void SetupDragHandlers(WindowPtr win) {
  19.     static DragTrackingHandlerUPP trackingHandler=0;
  20.     static DragReceiveHandlerUPP receiveHandler=0;
  21.  
  22.     if (! trackingHandler) trackingHandler = NewDragTrackingHandlerProc(SampleTrackingHandler);
  23.     if (! receiveHandler) receiveHandler = NewDragReceiveHandlerProc(SampleReceiveHandler);
  24.         
  25.     if (trackingHandler && receiveHandler) {
  26.         InstallTrackingHandler(trackingHandler, win, 0);
  27.         InstallReceiveHandler(receiveHandler, win, 0);
  28.         }
  29.     }
  30.  
  31. // ***********************************************************************************
  32. // ***********************************************************************************
  33.  
  34. short SampleWindowDrag(EventRecord *theEvent, WindowPtr win) {
  35.     short err=0;
  36.     Str255 textBuff;
  37.     RgnHandle dragRgn;
  38.     DragReference dragRef=0;
  39.     DragAttributes attributes;
  40.     
  41.     // If the user just clicks and lets go, then return
  42.     if (! WaitMouseMoved(theEvent->where)) return(0);
  43.     
  44.     // Setup the information we need to do a Drag
  45.     err = NewDrag(&dragRef);
  46.     if (err) return(err);
  47.  
  48.     dragRgn = NewDragRgn(win);
  49.     if (!dragRgn) goto HANDLE_ERROR;
  50.  
  51.     // Add in some data - The contents of our window
  52.     BlockMove(GetSampleWindowText(win), textBuff, sizeof(textBuff));
  53.     err = AddDragItemFlavor(dragRef, 1, 'TEXT', textBuff+1, textBuff[0], 0);    
  54.  
  55.  
  56.     // Initiate the dragging process, and handle any errors by escaping
  57.     err = TrackDrag(dragRef, theEvent, dragRgn);
  58.     if (err == userCanceledErr) err = 0;
  59.     if (err) goto HANDLE_ERROR;
  60.     
  61.     GetDragAttributes(dragRef, &attributes);
  62.     if (! (attributes & dragInsideSenderApplication)) {
  63.         AEDesc dropLocation;
  64.  
  65.         GetDropLocation(dragRef, &dropLocation);
  66.  
  67.  
  68.         AEDisposeDesc(&dropLocation);
  69.         }
  70.  
  71.     
  72. HANDLE_ERROR:
  73.     if (dragRef) DisposeDrag(dragRef);
  74.     if (dragRgn) DisposeRgn(dragRgn);
  75.     return(err);
  76.     }
  77.  
  78. // ***********************************************************************************
  79. // ***********************************************************************************
  80.  
  81. pascal OSErr SampleTrackingHandler(DragTrackingMessage message, WindowPtr win,
  82.         void *refcon, DragReference dragRef) {
  83.     static Boolean acceptDrag, inContent;
  84.     short err=0;
  85.     unsigned short count;
  86.     unsigned long flavorFlags;
  87.     Point localPt;
  88.     GrafPtr savePort;
  89.     RgnHandle hiliteRgn;
  90.     ItemReference dragItem;
  91.     DragAttributes attributes;
  92.     
  93.     GetDragAttributes(dragRef, &attributes);
  94.     
  95.     GetPort(&savePort);
  96.     SetPort(win);
  97.     
  98.     switch (message) {
  99.         case dragTrackingEnterHandler:
  100.             acceptDrag = FALSE;
  101.             inContent = FALSE;
  102.             break;
  103.             
  104.         case dragTrackingEnterWindow:
  105.             // Test every Drag Item to see if it contains text
  106.             if (CountDragItems(dragRef, &count)) count=0;
  107.             for(count, acceptDrag = TRUE; count && acceptDrag; count--) {
  108.                 GetDragItemReferenceNumber(dragRef, count, &dragItem);
  109.  
  110.                 if (err = GetFlavorFlags(dragRef, dragItem, 'TEXT', &flavorFlags))
  111.                     acceptDrag = FALSE;
  112.                 }
  113.             break;
  114.  
  115.         case dragTrackingInWindow:
  116.             if (! acceptDrag) break;
  117.             
  118.             GetDragMouse(dragRef, &localPt, 0L);
  119.             GlobalToLocal(&localPt);
  120.             
  121.             if (attributes & dragHasLeftSenderWindow) {
  122.                 if (! inContent) {
  123.                     if (hiliteRgn = NewRgn()) {
  124.                         RectRgn(hiliteRgn, &win->portRect);
  125.                         ShowDragHilite(dragRef, hiliteRgn, TRUE);
  126.                         DisposeRgn(hiliteRgn);
  127.                         }
  128.                     inContent = TRUE;
  129.                     }
  130.                 }
  131.               else {
  132.                 if (inContent) {
  133.                     HideDragHilite(dragRef);
  134.                     inContent = FALSE;
  135.                     }
  136.                 }
  137.             break;
  138.         case dragTrackingLeaveWindow:
  139.             if (acceptDrag && inContent) HideDragHilite(dragRef);
  140.             acceptDrag = FALSE;
  141.             inContent = FALSE;
  142.             break;
  143.         case dragTrackingLeaveHandler:
  144.             break;
  145.         }
  146.  
  147.     SetPort(savePort);
  148.     }
  149.  
  150. // ***********************************************************************************
  151. // ***********************************************************************************
  152.  
  153. pascal OSErr SampleReceiveHandler(WindowPtr win, void *refcon, DragReference dragRef) {
  154.     Boolean handled;
  155.     unsigned short count;
  156.     unsigned long flavorFlags;
  157.     Size dataSize;
  158.     Str255 textBuff;
  159.     GrafPtr savePort;
  160.     ItemReference dragItem;
  161.     DragAttributes attributes;
  162.  
  163.     // Test every Drag Item to see if it contains text
  164.     if (CountDragItems(dragRef, &count)) count=0;
  165.     for(count, handled=FALSE; count && !handled; count--) {
  166.         GetDragItemReferenceNumber(dragRef, count, &dragItem);
  167.         if (GetFlavorFlags(dragRef, dragItem, 'TEXT', &flavorFlags)) continue;
  168.         
  169.         GetFlavorDataSize(dragRef, dragItem, 'TEXT', &dataSize);
  170.         textBuff[0] = dataSize = (dataSize <= 255) ? dataSize : 255;
  171.         GetFlavorData(dragRef, dragItem, 'TEXT', (Ptr) textBuff+1, &dataSize, 0L);
  172.         handled = TRUE;
  173.         }
  174.     
  175.     if (handled) SetSampleWindowText(win, textBuff);
  176.     return((handled) ? 0 : -1);
  177.     }
  178.  
  179. // ***********************************************************************************
  180. // ***********************************************************************************
  181.  
  182. RgnHandle NewDragRgn(WindowPtr win) {
  183.     Point convertPt;
  184.     GrafPtr savePort;
  185.     RgnHandle dragRgn=0, tempRgn=0;
  186.     
  187.     dragRgn = NewRgn();
  188.     tempRgn = NewRgn();
  189.     if (! dragRgn || ! tempRgn) return(0);
  190.     
  191.     // Build up a region that's 1 pixel thick, as per Drag Mgr dox
  192.     RectRgn(dragRgn, &win->portRect);
  193.     InsetRgn(dragRgn, 3, 3);
  194.     CopyRgn(dragRgn, tempRgn);
  195.     InsetRgn(tempRgn, 1, 1);
  196.     DiffRgn(dragRgn, tempRgn, dragRgn);
  197.     DisposeRgn(tempRgn);
  198.     
  199.     // Convert the coords of our rgn (ala PortRect) from Local to Global
  200.     GetPort(&savePort);
  201.     SetPort(win);
  202.     SetPt(&convertPt, 0, 0);
  203.     LocalToGlobal(&convertPt);
  204.     SetPort(savePort);
  205.     OffsetRgn(dragRgn, convertPt.h, convertPt.v);
  206.     
  207.     return(dragRgn);
  208.     }
  209.